import { isObject } from '../shared'
import {
  mutableHandlers,
  shallowReactiveHandlers,
} from "./baseHandlers"

export const reactiveMap = new WeakMap()
export const shallowReactiveMap = new WeakMap()

export const ReactiveFlags = {
  IS_REACTIVE: "__v_isReactive",
  RAW: "__v_raw",
}

export function reactive(target) {
  return createReactiveObject(target, reactiveMap, mutableHandlers)
}
export function shallowReactive(target) {
  return createReactiveObject(
    target,
    shallowReactiveMap,
    shallowReactiveHandlers
  )
}

/**
 * 判断是不是有 `__isReactive` 属性
 * @param {*} value 
 * @returns 
 */
export function isReactive(value) {
  return !!value[ReactiveFlags.IS_REACTIVE]
}

/**
 * 通过 proxy 创建代理，不同的 map 存储不同类型的 reactive 依赖关系。
 * 针对普通的对象和 es6 的 map、set 等数据结构，需要使用不同的 handlers，
 * 这里没实现 map 等数据结构的 collectionHandlers，有兴趣可以去 vue 源码中自己学习
 * @param {Object} target 
 * @param {Map} proxyMap 
 * @param {Object} proxyHandlers 
 * @returns 
 */
function createReactiveObject(target, proxyMap, proxyHandlers) {
  if (!isObject(target)) {
    console.warn(`reactive ${target} 必须是一个对象`)
    return target
  }

  // 缓存找到了，直接返回
  const existingProxy = proxyMap.get(target)
  if (existingProxy) {
    return existingProxy
  }

  // 执行代理
  const proxy = new Proxy(target, proxyHandlers)

  // 缓存新代理
  proxyMap.set(target, proxy)
  return proxy
}
